home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright © 1991-1995 by TopSoft Inc. All rights reserved.
-
- You may distribute this file under the terms of the TopSoft
- Artistic License, accompanying this package.
-
- This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
- See the Modification History for more details.
-
- Product
- About Box
-
- FILE
- ABTopicList.c
-
- NAME
- ABTopicList.c, part of the ABox project source code,
- responsible for handling the AboutBox Topic List class stuff.
-
- DESCRIPTION
- This file contains defines for the about box modules.
-
- DEVELOPED BY
- George (ty) Tempel ttempel@monmouth.com
- All code in this file, and its associated header file was
- Created by George (ty) Tempel in connection with the TopSoft, Inc.
- "FilterTop" application development, except where noted.
-
- CARETAKER - George (ty) Tempel <ttempel@monmouth.com>
- Please consult this person for any changes or suggestions to this file.
-
- MODIFICATION HISTORY
-
- dd mmm yy - xxx - patchxx: description of patch
- 9 June 94 - ty - Initial Version Created
- 15-july-94 - ty - modifications to include ABUFSSpecs mix-in class
- 20-july-94 - ty - initial version released
- 23-may-95 - ty - changes for compatibility with the CodeWarrior CW6
- release and the associated Universal Headers from Apple:
- most methods that returned references now have "Ref" at
- the end of their methods names to prevent possible collisions
- with datatypes and classes of the same name (older versions
- of the compiler didn't have a problem with this).
- 25-oct-95 - ty - changes for "const" usage under CW7; simplification of Boolean
- query methods
-
- */
-
- /*===========================================================================*/
-
- /*======= Segmentation directives ========*/
-
- #ifdef USE_MANUAL_SEGMENTATION
- #pragma segment ty
- #endif
-
- /*============ Header files ==============*/
-
- #include "ABTopicList.h"
- #include "ABoxDefs.h"
-
-
- /*=============== Globals ================*/
-
- /*================ CODE ==================*/
-
-
-
-
-
-
- /*=============================== ABTopicList::ABTopicList ================================*/
- ABTopicList::ABTopicList(void)
- {
- mDefaultResFileRefNum = 0;
- } // end ABTopicList
-
-
-
- /*=============================== ABTopicList::~ABTopicList ================================*/
- ABTopicList::~ABTopicList(void)
- {
- } // end ~ABTopicList
-
-
-
-
-
-
- /*=============================== ABTopicList::GotoLink ================================*/
- ABLink *ABTopicList::GotoLink(ABIndex n)
- {
- OSErr error = noErr;
-
- // begin here...
-
- if (this->HasCurrentLink())
- error = ((ABTopic *) this->CurrentLink())->CloseTopic();
-
- // currentLink = NthLink(n);
-
- if (ABLinkedList::GotoLink(n))
- error = ((ABTopic *) this->CurrentLink())->OpenTopic();
-
- return this->CurrentLink();
- } // end GotoLink
-
-
-
-
-
- /*=============================== ABTopicList::PreviousLink ================================*/
- ABLink *ABTopicList::PreviousLink(void)
- {
- OSErr error = noErr;
-
- // begin here...
-
- if (this->HasCurrentLink())
- error = ((ABTopic *) this->CurrentLink())->CloseTopic();
-
- ABLinkedList::PreviousLink();
-
- if (this->HasCurrentLink())
- error = ((ABTopic *) this->CurrentLink())->OpenTopic();
-
- return this->CurrentLink();
- } // end PreviousLink
-
-
-
- /*=============================== ABTopicList::NextLink ================================*/
- ABLink *ABTopicList::NextLink(void)
- {
- OSErr error = noErr;
-
- // begin here...
-
- if (this->HasCurrentLink())
- error = ((ABTopic *) this->CurrentLink())->CloseTopic();
-
- ABLinkedList::NextLink();
-
- if (this->HasCurrentLink())
- error = ((ABTopic *) this->CurrentLink())->OpenTopic();
-
- return this->CurrentLink();
- } // end NextLink
-
-
-
- /*=============================== ABTopicList::FirstLink ================================*/
- ABLink *ABTopicList::FirstLink(void)
- {
-
- if (this->IsntEmpty())
- return this->GotoLink (1);
- else
- return NULL;
- } // end FirstLink
-
-
-
- /*=============================== ABTopicList::LastLink ================================*/
- ABLink *ABTopicList::LastLink(void)
- {
- if (this->IsntEmpty())
- return this->GotoLink (this->Count());
- else
- return NULL;
- } // end LastLink
-
-
-
- /*=============================== ABTopicList::TryTopics ===============================*/
- //
- ABTopic* ABTopicList::TryTopics(FSSpec& inFileSpec)
- {
- OSErr error = noErr;
-
- ABTopic* theTopic = NULL;
-
- theTopic = this->TryTopic(inFileSpec, ETopicType_OtherTopic);
- if (theTopic == NULL)
- theTopic = this->TryTopic(inFileSpec, ETopicType_Topic);
- if (theTopic == NULL)
- theTopic = this->TryTopic(inFileSpec, ETopicType_MovieTopic);
-
- return theTopic;
- }
-
-
-
- /*=============================== ABTopicList::TryTopic ===============================*/
- //
- ABTopic* ABTopicList::TryTopic(FSSpec& inFileSpec, ETopicType inTopicType)
- {
- OSErr error = noErr;
-
- ABTopic* theTopic = NULL;
-
- switch (inTopicType)
- {
- case ETopicType_OtherTopic:
- theTopic = new ABOtherTopic(inFileSpec);
- break;
-
- case ETopicType_Topic:
- theTopic = new ABTopic(inFileSpec);
- break;
-
- case ETopicType_MovieTopic:
- theTopic = new ABMovieTopic(inFileSpec);
- break;
- default:
- break;
- }
-
- if (theTopic)
- {
- error = theTopic->Load();
-
- if (error != noErr)
- {
- delete theTopic;
- theTopic = NULL;
- }
- }
-
- return theTopic;
- }
-
-
-
- /*=============================== ABTopicList::RecurseDownFolderTree ===============================*/
- //
- // RecurseDownFolderTree will recursively descend a folder tree to accumulate a list
- // of Topic files. When a valid file is encountered it is appended to the list/array
- // of topics.
- //
- // The function has no return value, but it will return the number of items
- // processed in the caller-supplied *fileCount pointer (if the pointer is valid).
- //
- //
- // is called by:
- // Load
- // RecurseDownFolderTree
- //
- OSErr ABTopicList::RecurseDownFolderTree( FSSpecPtr top,
- short int depth,
- ABTopic *parentFolder)
- {
- OSErr error = noErr;
-
- long dirID;
- short vRefNum;
- const StringPtr nameStrForDir = NULL;
-
- Boolean sameString = false;
-
- short slideCount = 0;
- short currentResFile = CurResFile();
-
- ABTopic *t = NULL;
- ABTopic *swappedTopic = NULL;
-
- const short reqItemCount = 10;
- FSSpec topicFSSpecs[reqItemCount];
- short actItemCount;
- short itemIndex = 0;
- short index;
- short limit;
-
- const Boolean getFiles = true;
- const Boolean getFolders = true;
- Boolean isFolder = false;
- Boolean resolvedAliasChains = true;
- Boolean wasAliased = false;
- short topicDepth = depth;
- Boolean done = false;
-
- // begin here...
-
- if (!top)
- return paramErr;
-
- // first, resolve the "top" item
- error = ::ResolveAliasFile (top,
- resolvedAliasChains,
- &isFolder,
- &wasAliased);
- if (error)
- return error;
-
- if (! isFolder)
- return paramErr;
-
- // as a preflight, get the dirID and the vRefNum from
- // the "top" item. Also, copy the name as well
- vRefNum = top->vRefNum;
- error = ABUFSSpecs::DirIDFromFSSpec (top, // const FSSpec *spec
- &dirID, // long *dirID
- &isFolder); // Boolean *isDirectory
- if (error)
- return error;
-
- if (! isFolder)
- return paramErr;
-
- // next, loop until we've gotten all of the items from the directory
- itemIndex = 1;
- // starting with the first item, loop forever until we run out
- // of files, indicated by GetDirItems() returning fnfErr, which
- // we'll convert to a noErr and return
- done = false;
- while (!done)
- {
- // get a block of items from the directory
- error = ABUFSSpecs::GetDirItems (vRefNum, // short vRefNum
- dirID, // long dirID
- nameStrForDir, // StringPtr name
- getFiles, // Boolean getFiles
- getFolders, // Boolean getDirectories
- topicFSSpecs, // FSSpecPtr items
- reqItemCount, // short reqItemCount
- &actItemCount, // short *actItemCount (number returned)
- &itemIndex); // short *itemIndex (1 = first item, then keep reusing)
- if (error == fnfErr)
- {
- done = true;
- error = noErr;
- } // end if block
-
- if (error)
- return error;
-
- // now that we have a block of items from the directory,
- // try to process each of them in turn.
- //
- // actItemCount items were returned, out of a possible reqItemCount
- limit = (actItemCount < reqItemCount) ? actItemCount : reqItemCount;
- for (index = 0; index < limit; ++index)
- {
- // before we do _anything_, attempt to resolve any
- // aliases hanging around
- error = ::ResolveAliasFile (&(topicFSSpecs[index]),
- resolvedAliasChains,
- &isFolder,
- &wasAliased);
-
- t = this->TryTopics(topicFSSpecs[index]);
-
- if (t == NULL)
- // nothing could be made of the file, so skip it
- continue;
-
- // well, the topic works! Save it
-
- // NOTE: save the local stuff into the topic object
- //
- // copy the filename into the topic name
- ::BlockMove ((Ptr)(topicFSSpecs[index].name),
- (Ptr)(t->NameRef()),
- topicFSSpecs[index].name[0] + 1);
- // mark the depth at which this topic exists...
- t->SetDepth(topicDepth);
-
- // check to see if this file has the same name as
- // the enclosing folder.
- //
- sameString = false;
- if (parentFolder)
- sameString = ::EqualString(t->NameRef(),
- parentFolder->GetName(),
- kABcaseSensitive,
- kABdiacriticalSensitive);
-
- if (sameString && !isFolder)
- {
- // the file has the same name as the enclosing folder
- // so substitute this topic for the parent folder.
-
- swappedTopic = (ABTopic *)parentFolder->ExchangeWith(t);
- t->SetDepth(parentFolder->GetDepth());
- delete swappedTopic;
- swappedTopic = parentFolder = NULL;
- } else {
- // the file does _not_ have the same name as the enclosing
- // folder, so save the information as a file.
- this->Append(t);
-
- } // end if (sameString) else block
-
- if (isFolder)
- {
- error = this->RecurseDownFolderTree( &(topicFSSpecs[index]),
- depth + 1,
- t); // recursive call
- if (error)
- return error;
-
- } // end if (isFolder)
-
- // now process the next item in the block
-
- } // end for (index) block...
- } // end while (forever) loop
-
- return error;
-
- } // end of function RecurseDownFolderTree()
-
-
-
-
-
- /*=============================== ABTopicList::Load ===============================*/
- //
- // CountAndLoadTopics will load an FSSpec for each of the topic
- // files in the designated folder.
- //
- // The caller can provide a pointer to a short integer value
- // if it wishes to receive the number of items processed.
- //
- // Any errors will be evident via the return value of the function.
- //
- //
- // is called by:
- // CreateAndFillTopicList
- //
- OSErr ABTopicList::Load (FSSpecPtr top, short defaultRefNum)
- {
- OSErr error = noErr;
-
- Str255 tName;
- const short int depth = 0;
-
- ABTopic *t = NULL;
- short currentResFile = ::CurResFile();
-
- // begin here...
-
- ABUCursor::WatchCursor();
- this->DefaultResFileRefNum() = defaultRefNum;
- t = new ABTopic();
- if (!t)
- {
- error = ::MemError();
- ABUCursor::ArrowCursor();
- return error;
- } // end if block
-
- // first grab a topic and slides from the application
- // if at all possible.
- error = t->Load (this->DefaultResFileRefNum());
-
- if (!top || error)
- {
- // the fsspec was bad or missing, so we had to
- // deal with just the topic stored in the application.
- // We'll bail here.
- //
- ::UseResFile (currentResFile);
- delete t;
- if (!top)
- {
- ABUCursor::ArrowCursor();
- return error;
- } // end if block
- } else if (!error) {
- // if there were topics (primary slides) stored inside the application
- // we'll pop those into the topics list first.
- //
- ::GetIndString (tName, kABStrings, kABdefaultTopicName);
- ::BlockMove ((Ptr)tName, (Ptr)(t->NameRef()), *tName + 1);
- t->SetDepth(0);
-
- this->Append(t);
- } // end if block...
-
- ::UseResFile (currentResFile);
-
-
- error = this->RecurseDownFolderTree( top, // input FSSpecPtr
- depth, // current depth marker
- NULL); // parent topic
-
- if ((error == fnfErr) || (error == dirNFErr))
- error = noErr;
-
- ABUCursor::ArrowCursor();
- return error;
-
- } // end of function CountAndLoadTopics()
-
-
-
-
-
-
-
-
- // end of file
-